package com.dengtacj.puppeteerspider.actions;


import cn.hutool.crypto.SecureUtil;

import com.dengtacj.puppeteerspider.config.PuppeteerConfig;
import com.dengtacj.puppeteerspider.enties.SpAnnouncementInfoLettersBean;
import com.dengtacj.puppeteerspider.utils.JDBCTemplateUtil;
import com.dengtacj.puppeteerspider.utils.DateUtils;
import com.dengtacj.puppeteerspider.utils.SQLMergeParamsUtils;
import com.ruiyun.jvppeteer.core.browser.Browser;
import com.ruiyun.jvppeteer.core.page.ElementHandle;
import com.ruiyun.jvppeteer.core.page.Page;
import com.ruiyun.jvppeteer.options.PageNavigateOptions;
import lombok.extern.slf4j.Slf4j;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import redis.clients.jedis.Jedis;

import java.text.SimpleDateFormat;

import java.util.*;
import java.util.concurrent.ExecutionException;


@Slf4j
public class SpiderAction {

    private Integer tabCount;
    private Integer currentTabIndex = 1;

    private JdbcTemplate jdbcTemplate;


    private Browser browser = null;
    private Page page = null;

    public SpiderAction( ) {
        this.jdbcTemplate = new JDBCTemplateUtil().jdbcTemplate();
    }


    public void init(int tabIndex) {
        try {
            if (browser == null && page == null) {
                browser = new PuppeteerConfig().initBrowser();
                page = browser.newPage();
                //设置参数防止检测
                page.evaluateOnNewDocument("() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => undefined } }) }");
                page.evaluateOnNewDocument("() =>{ window.navigator.chrome = { runtime: {},  }; }");
                page.evaluateOnNewDocument("() =>{ Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }); }");
                page.evaluateOnNewDocument("() =>{ Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5,6], }); }");

                PageNavigateOptions pageNavigateOptions = new PageNavigateOptions();
                List<String> waitUtil = new ArrayList<>();
                waitUtil.add("domcontentloaded");
                pageNavigateOptions.setWaitUntil(waitUtil);
            }

            pageSearch(page, tabIndex);
            page.waitFor("5000");

            String maxPageNum = "0";
            if (currentTabIndex.equals(1)) {
                page.waitFor("#main_wxhj_paginator_tab2");
                maxPageNum = (String) page.$eval("#main_wxhj_nav1 .table-content.table_content_tab2 .current-page >span.num-all", "function(e){return e.innerText}");
            } else {
                page.waitFor("#main_wxhj_paginator_tab3");
                maxPageNum = (String) page.$eval("#main_wxhj_nav2 .table-content.table_content_tab3 .current-page >span.num-all", "function(e){return e.innerText}");
            }

            log.info("当前页面共有: " + maxPageNum + "页数据");

            int maxPage_int = Integer.parseInt(maxPageNum);
            String currentPageNum = "";
            for (int i = 0; i < maxPage_int; i++) {

                if (currentTabIndex.equals(1)) {
                    currentPageNum = (String) page.$eval("#main_wxhj_nav1 .table-content.table_content_tab2 .current-page >span.num-cur", "function(e){return e.innerText}");
                    getTableData(browser, page, currentPageNum, maxPageNum);
                    page.evaluate("function(){ let dom=document.querySelector('#main_wxhj_paginator_tab2>li.next>a'); if(dom){dom.click()} }", new ArrayList<>());
                } else {
                    currentPageNum = (String) page.$eval("#main_wxhj_nav2 .table-content.table_content_tab3 .current-page >span.num-cur", "function(e){return e.innerText}");
                    getTableData(browser, page, currentPageNum, maxPageNum);
                    page.evaluate("function(){ let dom=document.querySelector('#main_wxhj_paginator_tab3>li.next>a'); if(dom){dom.click()} }", new ArrayList<>());
                }

                page.waitFor("500");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            log.error("error: " + e.toString());
        }
    }

    /**
     * 初始化爬取的数据 所需要的初始化的查询条件
     */
    private void pageSearch(Page page, int tabIndex) {
        try {
            page.goTo("http://www.szse.cn/disclosure/supervision/inquire/index.html");
            page.waitFor("20000");
            page.waitFor("#main_wxhj_query_txtStart input");

            tabCount = (Integer) page.$eval(".nav.nav-tabs", "function(e){return e.children.length}");

            page.click(".nav.nav-tabs>li:nth-child(" + tabIndex + ")>a");
            page.waitFor("3000");


            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd");
            Date date = new Date();
            String endDate = simpleDateFormat.format(date);
            String startDate = DateUtils.getPastDate(30,null);

            if (currentTabIndex.equals(1)) {
                page.type("input#main_wxhj_tab2_txtStart", startDate);
                page.type("input#main_wxhj_tab2_txtEnd", endDate);
                page.click(".condition_tab2 button.confirm-query.btn-query-primary");
            } else {
                page.type("input#main_wxhj_tab3_txtStart", startDate);
                page.type("input#main_wxhj_tab3_txtEnd", endDate);
                page.click(".condition_tab3 button.confirm-query.btn-query-primary");
            }


        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            log.error("点击的元素不存在" + e.toString());
        }

    }


    private void getTableData(Browser browser, Page page, String pageNum, String maxPageNum) {
        log.info("当前爬取的是第" + pageNum + "页");
        List<ElementHandle> domList = null;
        try {
            if (currentTabIndex.equals(1)) {
                page.waitFor("div.table_content_tab2 table.table.table-responsive.table-tab1>tbody>tr");
                domList = page.$$("div.table_content_tab2 table.table.table-responsive.table-tab1 >tbody >tr");
            } else {
                page.waitFor("div.table_content_tab3 table.table.table-responsive.table-tab1>tbody>tr");
                domList = page.$$("div.table_content_tab3 table.table.table-responsive.table-tab1 >tbody >tr");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            if (currentTabIndex.equals(1)) {
                log.error("当前dom找不到 -> div.table_content_tab2 table.table.table-responsive.table-tab1>tbody>tr " + e.toString());
            } else {
                log.error("当前dom找不到 -> div.table_content_tab3 table.table.table-responsive.table-tab1>tbody>tr " + e.toString());
            }
        }
        log.info("当前页共有" + domList.size() + "条数据");
        for (int i = 0; i < domList.size(); i++) {

            String domNode = null;
            if (currentTabIndex.equals(1)) {
                domNode = "div.table_content_tab2 table.table.table-responsive.table-tab1 >tbody>tr:nth-child(" + (i + 1) + ")> td:nth-child";
                Integer childrenCount = (Integer) page.$eval("div.table_content_tab2 table.table.table-responsive.table-tab1 >tbody>tr:nth-child(" + (i + 1) + ")", "function(e){return e.children.length }");
                if (childrenCount < 5) {
                    continue;
                }
            } else {
                domNode = "div.table_content_tab3 table.table.table-responsive.table-tab1 >tbody>tr:nth-child(" + (i + 1) + ")> td:nth-child";
                Integer childrenCount = (Integer) page.$eval("div.table_content_tab3 table.table.table-responsive.table-tab1 >tbody>tr:nth-child(" + (i + 1) + ")", "function(e){return e.children.length }");
                if (childrenCount < 5) {
                    continue;
                }
            }
            String pdfUrl = (String) page.$eval(domNode + "(5)>a", "(e)=> e.getAttribute('encode-open')");
            String stockname = (String) page.$eval(domNode + "(2)", "(e)=>e.innerText");
            String stockId = (String) page.$eval(domNode + "(1)", "(e)=>e.innerText");
            String title = (String) page.$eval(domNode + "(5)>a", "(e)=> e.innerHTML");
            if (title.equals("详细内容")) {
                title = "关于" + stockname + "的问询函件";
            }

            SpAnnouncementInfoLettersBean spAnnouncementInfoLettersBean = new SpAnnouncementInfoLettersBean();
            spAnnouncementInfoLettersBean.setTitle(title);
            spAnnouncementInfoLettersBean.setState(1);
            spAnnouncementInfoLettersBean.setSource("深交所");
            spAnnouncementInfoLettersBean.setSource_url("http://www.szse.cn/disclosure/supervision/inquire/index.html");
            String md5Url = SecureUtil.md5(pdfUrl);
            spAnnouncementInfoLettersBean.setUrl(pdfUrl);
            spAnnouncementInfoLettersBean.setReport_id(md5Url);
            spAnnouncementInfoLettersBean.setStockname(stockname);
            spAnnouncementInfoLettersBean.setStockId(stockId);
            String sta_time = (String) page.$eval(domNode + "(3)", "(e)=>e.innerText");

            spAnnouncementInfoLettersBean.setSta_time(sta_time);
            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String format = simpleDateFormat.format(date);
            spAnnouncementInfoLettersBean.setCreate_time(format);

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            insertData(spAnnouncementInfoLettersBean, maxPageNum, pageNum);
        }


        if (maxPageNum.equals(pageNum)) {
            if (tabCount.equals(currentTabIndex)) {
                browser.close();
            } else {
                currentTabIndex++;
                init(currentTabIndex);
            }
        }
    }

    private void insertData(SpAnnouncementInfoLettersBean spAnnouncementInfoLettersBean, String maxPage, String currentPage) {

        String sp_announcement_crawled_info_letters = null;
        try {
            sp_announcement_crawled_info_letters = SQLMergeParamsUtils.getObjectValue(spAnnouncementInfoLettersBean, "sp_announcement_crawled_info_letters");
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info(sp_announcement_crawled_info_letters);

        Boolean aBoolean = hasOne(spAnnouncementInfoLettersBean.getReport_id());
        if (!aBoolean) {
            jdbcTemplate.execute(sp_announcement_crawled_info_letters);
        } else {
            log.info("已保存数据库");
        }

    }

    private Boolean hasOne(String reportId) {

        String sql = "SELECT *  from  sp_announcement_crawled_info_letters WHERE report_id=" + "\"" + reportId + "\"";
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet(sql);
        boolean next = sqlRowSet.next();
        return next;
    }

}
